package org.zn.note.jdk.net;

import org.zn.note.common.util.ThreadUtil;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.Future;

/**
 * @ClassName JavaAIO
 * @Author zn
 * @Date 2019/4/29 16:09
 **/
// JDK 1.7 Asynchronous I/O
public class JavaAIO {

    public static final String FILE_PATH_A = "d:/test/a.txt";
    public static final String FILE_PATH_B = "d:/test/b.txt";
    public static final int MEMORY_KB = 1024;
    public static final int MEMORY_MB = 1024 * MEMORY_KB;
    public static final int BUFFER_CAPACITY = 20 * MEMORY_MB;

    // 异步处理方式一：轮询判断状态
    private static byte[] readByFuture() throws IOException {
        AsynchronousFileChannel fileChannel =
                AsynchronousFileChannel.open(Paths.get(FILE_PATH_A), StandardOpenOption.READ);
        ByteBuffer buffer = ByteBuffer.allocate(BUFFER_CAPACITY);
        long position = 0L;
        Future<Integer> operation = fileChannel.read(buffer, position);
        while (!operation.isDone()) {
            ThreadUtil.printThread("数据还没准备好 ...");
        }
        fileChannel.close();
        return buffer.array();
    }

    // 异步处理方式二：回调
    private static void writeByCompletionHandler(final byte[] bytes) throws IOException {
        AsynchronousFileChannel fileChannel =
                AsynchronousFileChannel.open(Paths.get(FILE_PATH_B), StandardOpenOption.WRITE);
        ByteBuffer buffer = ByteBuffer.allocate(BUFFER_CAPACITY);
        long position = 0L;
        buffer.put(bytes);
        buffer.flip();
        fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                ThreadUtil.printThread("Write bytes: " + result);
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                ThreadUtil.printThread("Write fail.");
            }
        });
        buffer.clear();
        fileChannel.close();
    }

    public static void main(String[] args) throws IOException {
        writeByCompletionHandler(readByFuture());
    }
}